package cz.spock.cms.controller;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.blobstore.BlobstoreService;
import com.google.appengine.api.blobstore.BlobstoreServiceFactory;

import cz.spock.cms.entity.BinaryDataHolder;
import cz.spock.cms.service.DataService;
import cz.spock.core.controller.BaseController;

@Controller
public class FileController extends BaseController {

    @Autowired
    private DataService dService;
    private BlobstoreService bService = BlobstoreServiceFactory.getBlobstoreService();

    @RequestMapping(value = "/cms/files", method = RequestMethod.GET)
    public ModelAndView allFiles(HttpServletRequest request, HttpServletResponse response) {
        System.out.println("/cms/files");
        List<BinaryDataHolder> dl = dService.findAllFiles();
        return new ModelAndView("cms/file/files", "pages", dl).addObject("files", dl);
    }

    @RequestMapping(value = "/cms/{user}/files", method = RequestMethod.GET)
    public ModelAndView userFiles(@PathVariable Long user, HttpServletRequest request, HttpServletResponse response) {
        System.out.println("/cms/" + user + "/files");
        List<BinaryDataHolder> dl = dService.findFileByUser(user);
        return new ModelAndView("cms/file/files", "pages", dl).addObject("files", dl);
    }

    @RequestMapping(value = "/cms/file/*", method = RequestMethod.GET)
    public void getFile(HttpServletRequest request, HttpServletResponse response) {
        System.out.println(request.getRequestURI());
        String uri = request.getRequestURI();
        uri = uri.replaceFirst("/file", "");
        BinaryDataHolder data = dService.findFileByUri(uri);
        try {
            if (data.getBlobstoreData() == null) {
                // datastore data
                response.setContentType(data.getContentType());
                response.getOutputStream().write(data.getDatastoreData().getBytes());
                response.flushBuffer();
            } else {
                // blobstore data
                bService.serve(data.getBlobstoreData(), response);
            }
        } catch (IOException e) {
            // TODO error handler
            e.printStackTrace();
            System.out.println("IOException");
        }
    }

    @RequestMapping(value = { "/cms/file/upload", "/cms/file/creates" }, method = RequestMethod.GET)
    public ModelAndView fileUploadToBlobstoreGet(HttpServletRequest request, HttpServletResponse response) {
        System.out.println("/cms/file/upload get");
        String url = bService.createUploadUrl("/cms/file/upload/blobstore");
        return new ModelAndView("cms/file/upload").addObject("uploadUrl", url).addObject("blobstore", true);
    }

    @RequestMapping(value = "/cms/file/upload/small", method = RequestMethod.GET)
    public ModelAndView fileUploadToDatastoreGet(HttpServletRequest request, HttpServletResponse response) {
        System.out.println("/cms/file/upload/small get");
        return new ModelAndView("cms/file/upload").addObject("blobstore", false);
    }

    @RequestMapping(value = "/cms/file/upload/blobstore/*", method = RequestMethod.POST)
    public String fileUploadToBlobstorePOST(HttpServletRequest request, HttpServletResponse response) {
        System.out.println("/cms/file/upload/blobstore POST");
        Map<String, BlobKey> blobs = bService.getUploadedBlobs(request);
        BlobKey blobKey = blobs.get(blobs.keySet().iterator().next());
        Long userId = this.getCurrentUser().getId();

        try {
            dService.createBlobstoreData(userId, 
                    request.getParameter("uri"), 
                    request.getParameter("title"), 
                    request.getParameter("description"), 
                    null, 
                    blobKey);        
        } catch(Exception e) {
            // TODO handle exception
            System.out.println("Exception in fileUploadToBlobstorePOST: " + e.getMessage());
        }

        return "redirect:/cms/" + this.getCurrentUser().getId() + "/files";
    }

    @RequestMapping(value = "/cms/file/upload/small", method = RequestMethod.POST)
    public String fileUploadToDatastorePost(HttpServletRequest request, HttpServletResponse response) {
        System.out.println("/cms/file/upload/small post");

        return "redirect:/cms/" + this.getCurrentUser().getId() + "/files";
    }

}
